<?php
/**
 * @Description 模型验证模块
 * @Sonkwl Xiong
 * @Date 2022/02/22 11:14:14
 */
namespace procjson;

class model{
    static $json=array();
    /**
     * 常规请求模型
     * ---
     * 前端请求json的key ,必须满足model_command的定义
     * ---
     */
    static public $model_command=array(
        "jwt"=>array("command","token"),
        "login"=>array("command","table","clause","id"),
        "query"=>array("command","table","clause"),
        "select"=>array("command","table","clause"),
        "insert"=>array("command","table","clause"),
        "update"=>array("command","table","clause","update"),
        "delete"=>array("command","table","clause"),
        "insertNoExists"=>array("command","table","clause","noexists"),
        "insertAfterDelete"=>array("command","table","clause","delete")
    );
    /**
     * 请求模型比对，最小匹配算法
     */
    static public function CheckCommand($step){
        if(!isset($step["command"])){
            \procjson\http::Response(array("res"=>"NG","message"=>"没有定义command"));
        }
        if(!isset(self::$model_command[$step["command"]])){
            \procjson\http::Response(array("res"=>"NG","message"=>$step["command"]."没有定义command"));
        }
        $model_obj=self::$model_command[$step["command"]];
        foreach($model_obj as $v){
            if(!in_array($v,array_keys($step))){
                \procjson\http::Response(array("res"=>"NG","message"=>$step["command"]."中需要定义".$v));
            }
        }
    }

    //@Desc 开放模型
    static public $model_open=array(
        //user table 测试用例
        // "user"=>array(
        //     //登录模型
        //     "login"=>array(
        //         "command"=>"login",
        //         "table"=>"user",
        //         "clause"=>array("s_no","s_pwd"),
        //         "id"=>"s_no"//返回jwt token的栏位
        //     ),
        //     //查询模型
        //     "select"=>array(
        //         "command"=>"select",
        //         "table"=>"user",
        //         "clause"=>array("s_no","s_name"),
        //         "column"=>"s_no,s_name,s_mail"
        //     ),
        //     //更新模型
        //     "update"=>array(
        //         "command"=>"update",
        //         "table"=>"user",
        //         "clause"=>array("s_no"),
        //         "update"=>array("s_name","s_mail")
        //     )
        // )
    );

    //@Sonkwl Xiong 2022/02/22 09:10:23
    //@Desc 验证开放模型
    static public function CheckOpen($step,$session_no){
        //没有jwt验证，且当前不是jwt
        if($session_no=='@ALL' && $step["command"]!="jwt"){
            if(!isset(self::$model_open[$step["table"]]) || !isset(self::$model_open[$step["table"]][$step["command"]])){
                \procjson\http::Response(array("res"=>"NG","message"=>"系统未开放".$step["table"]."的".$step["command"]."功能"));
            }
            //获取模型
            $model_obj=self::$model_open[$step["table"]][$step["command"]];
            if($model_obj["command"]!=$step["command"]){
                \procjson\http::Response(array("res"=>"NG","message"=>"开放模型".$step["table"]."的".$step["command"]."定义错误"));
            }
            if($model_obj["table"]!=$step["table"]){
                \procjson\http::Response(array("res"=>"NG","message"=>"开放模型".$step["table"]."的".$step["table"]."定义错误"));
            }
            if(array_keys($model_obj)!=array_keys($step)){
                \procjson\http::Response(array("res"=>"NG","message"=>$step["table"]."的".$step["command"]."与系统开放模型定义不一致"));
            }

            //验证clause
            if($step["command"]=="login" || $step["command"]=="delete" || $step["command"]=="insert" || $step["command"]=="update"){
                if($model_obj["clause"]!=array_keys($step["clause"])){
                    \procjson\http::Response(array("res"=>"NG","message"=>"开放模型".$step["table"]."使用".$step["command"]."时，clause必须和模型一致"));
                }
                foreach($model_obj["clause"] as $v){
                    if(!in_array($v,array_keys($step["clause"]))){
                        \procjson\http::Response(array("res"=>"NG","message"=>"开放模型".$step["table"]."的clause中没有".$v));
                    }
                }
                //update
                if($step["command"]=="update" && $model_obj["update"]!=array_keys($step["update"])){
                    \procjson\http::Response(array("res"=>"NG","message"=>"开放模型".$step["table"]."使用".$step["command"]."时，update必须和模型一致"));
                }
            }
            if($step["command"]=="select" || $step["command"]=="query"){
                foreach($step["clause"] as $k=>$v){
                    if(!in_array($k,$model_obj["clause"])){
                        \procjson\http::Response(array("res"=>"NG","message"=>$step["table"]."的".$step["clause"]."中没有".$k));
                    }
                }
                if(!isset($step["column"]) || !isset($model_obj["column"])){
                    \procjson\http::Response(array("res"=>"NG","message"=>"开放的query,select必须定义column"));
                }
                //print($step["column"]);
                if($model_obj["column"]!=$step["column"]){
                    \procjson\http::Response(array("res"=>"NG","message"=>$step["table"]."的".$step["column"]."定义与系统开放模型的模型不一致"));
                }
            }
        }
    }

    /**
     * 强制模型
     * ---
     * 有些table涉及敏感信息
     * 1.防止敏感信息查询
     * 2.防止非权限信息查询
     * ---
     */
    static public $model_fixed=array(
        // "user"=>array(
        //     "query"=>array(
        //         "command"=>"query",
        //         "table"=>"user",
        //         "clause"=>array("s_no"=>""),
        //         "column"=>"s_no,s_name"
        //     )
        // )
    );
    static public function CheckFixed($step,$session_no){
        if($session_no=='@ALL' || $step["command"]=="jwt"){
            //没有jwt验证，且当前不是jwt
            return;
        }
        if(count(self::$model_fixed)==0){
            //无强制模型
            return;
        }
        if(!isset(self::$model_fixed[$step["table"]])){
            //无对应强制模型
            return;
        }
        if(!isset(self::$model_fixed[$step["table"]][$step["command"]])){
            //无对应的command
            return;
        }
        $objModel=self::$model_fixed[$step["table"]][$step["command"]];
        if($objModel["command"]!=$step["command"]){
            \procjson\http::Response(array("res"=>"NG","message"=>$step["table"].'的'.$step["command"].'强制定义错误'));
        }
        if($objModel["table"]!=$step["table"]){
            \procjson\http::Response(array("res"=>"NG","message"=>$step["table"].'的'.$step["table"].'强制定义错误'));
        }
        if(array_keys($objModel["clause"])!=array_keys($step["clause"])){
            \procjson\http::Response(array("res"=>"NG","message"=>$step["table"].'的clause强制定义错误'));
        }
        foreach($objModel["clause"] as $key=>$value){
            if($value!="" && $objModel["clause"][$key]!=$step["clause"][$key]){
                \procjson\http::Response(array("res"=>"NG","message"=>$step["table"].'的'.$step["clause"][$key].'强制定义错误'));
            }
        }
        if($objModel["column"]!=$step["column"]){
            \procjson\http::Response(array("res"=>"NG","message"=>$step["table"].'的'.$step["column"].'强制定义错误'));
        }
    }
}
?>